#include "ball.h"
#include "pingpong.h"

static const double Pi = 3.141592654;

Ball::Ball(int x, int y, int radius, double speed, int direction)
{
    this->setX(qreal(x));
    this->setY(qreal(y));
    this->radius = radius;
    this->xveloc = qreal(cos(direction*Pi/180));
    this->yveloc = qreal(-sin(direction*Pi/180));
    this->lastItemCollided = 0;
    this->speed = int(speed);
}
Ball::Ball()
{
}
QRectF Ball::boundingRect() const
{
    return QRectF(0, 0, radius-1, radius-1);
}
void Ball::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
    painter->setBrush(QBrush(Qt::red, Qt::SolidPattern));
    painter->drawEllipse(0,0,radius,radius);
}
void Ball::advance(int step)
{
    Q_UNUSED(step);

    QList<QGraphicsItem *> sceneItems = scene()->items();
    foreach (QGraphicsItem *item, sceneItems)
    {
        if(item == this || item == lastItemCollided) continue;
        else if(this->collidesWithItem(item) && item != lastItemCollided)
        {
            lastItemCollided = item;
            if(item->type() == QGraphicsLineItem().type()) //ball hits the wall (axis-aligned vector reflection)
            {
                emit collided();
                QGraphicsLineItem *tempitem = static_cast<QGraphicsLineItem*>(item);
                if(tempitem->line().angle() == 0)  // x-axis aligned
                {
                    yveloc = -yveloc;
                }
                if(tempitem->line().angle() == 270)  // y-axis aligned
                {
                    xveloc = -xveloc;
                    if(this->x() <= 0) {
                        emit wallCollided(true);
                    }
                    else {
                        emit wallCollided(false);
                    }
                }
            }
            else if (item->type() == Paddle().type())// ball hits the paddle
            {
                emit collided();
                Paddle *tempitem = static_cast<Paddle*>(item);
                qreal ballpaddleangle = MathOperations::getAngleXYOrigin(this->pos(),tempitem->pos(),true);
                if(tempitem->leftTopCCAngle <= ballpaddleangle && ballpaddleangle <= tempitem->rightTopCCAngle )
                {
                        if(yveloc >= 0) yveloc = -yveloc;
                        else this->setY(this->y()-abs(yveloc));

                }
                else if(tempitem->leftBottomCCAngle <= ballpaddleangle && ballpaddleangle <= tempitem->rightBottomCCAngle )
                {
                        if(yveloc < 0) yveloc = -yveloc;
                        else this->setY(this->y()+abs(yveloc));
                }
                else if(tempitem->leftTopCCAngle < ballpaddleangle && tempitem->leftBottomCCAngle > ballpaddleangle)
                {
                        xveloc = -xveloc;
                }
                else
                {
                        xveloc = -xveloc;
                }
                if (tempitem->getIsLeftPaddle()) emit leftPaddleCollided(100);
            }
        }
    }
    for(int i = 0; i < speed; ++i)
    {
        this->setPos(this->mapToParent(xveloc,yveloc));
    }
}
QPainterPath Ball::shape() const
{
    QPainterPath path;
    path.addEllipse(this->boundingRect());
    return path;
}
Ball::~Ball()
{
}
